package com.gitee.wsl.ext.map


/**
 * Transforms a map of lists into a list of pairs. Notice that the result can contain multiple
 * pairs that have the same first element. So, calling [toMap] won't revert the process
 */
fun <T : Any, R : Any> Map<T, List<R>>.flattenList(): List<Pair<T, R>> {
    return toList()
        .map { i -> i.second.map { j -> i.first to j } }
        .flatten()
}

/**
 * Transforms a map of lists into a list of pairs skipping null elements. Notice that the result can contain multiple
 * pairs that have the same first element. So, calling [toMap] won't revert the process
 */
fun <T : Any, R : Any> Map<T?, List<R>?>.flattenListNotNull(): List<Pair<T, R>> {
    return buildList {
        this@flattenListNotNull.forEach { entry ->
            val key = entry.key
            val value = entry.value
            if (key != null && value != null) {
                value.forEach { add(key to it) }
            }
        }
    }
}

fun <K, V> Iterable<Map<K, V>>.flatten(): Map<K, V> =
    flatMap { it.entries }.associate { it.key to it.value }
